// ================================================== //
// #			GameServer 1.00.90					# //
// #			Imagination Arts					# //
// #			Julia Project 1.1.x					# //
// ================================================== //
// #	http://imaginationarts.net/forum/			# //
// #	http://mu.raklion.ru/						# //
// ================================================== //

#include "StdAfx.h"
#include "Configs.h"
#include "Maps.h"
#include "Fixes.h"
#include "Utilits.h"
#include "Protocol.h"
#include "Logger.h"
#include "Security.h" 
#include "AntiAFK.h"
#include "DuelManager.h" 
#include "MoveReq.h"
#include "PCPoint.h"
#include "ChatCommands.h"
#include "MossGambler.h"	 
#include "Monster.h"  
#include "Query.h"
#include "Vip.h"
#include "HappyHour.h"
#include "Territory.h"
#include "News.h"
//#include "Protection.h"
#include "OffTrade.h"
#include "ResetSystem.h"
#include "Socket.h"
#include "TradeSystem.h"

DWORD MainTick()  	
{
	while(true)
	{
		CTime ct = CTime::GetCurrentTime();
		int Temp_All = 0;
		int Temp_Gms = 0;
		for(int i=0; i<OBJECT_MIN; i++)
		{
			if(AddTab[i].TEMP_Golden_Drop)
				AddTab[i].TEMP_Golden_Drop = false;
		}
		for(int i=OBJECT_MIN; i<=OBJECT_MAX; i++)
		{
			OBJECTSTRUCT *gObj = (OBJECTSTRUCT*)OBJECT_POINTER(i);	

			// # PLAYER  LOGGED # //

			if(gObj->Connected < PLAYER_LOGGED) continue;

			if(GmSystem.IsGMBD(gObj->Name))
				Temp_Gms++;
			Temp_All++;

			// # -------------- # //

			// # PLAYER PLAYING # //

			if(gObj->Connected < PLAYER_PLAYING) continue;				

			if(AddTab[gObj->m_Index].POST_Delay > 0)
				AddTab[gObj->m_Index].POST_Delay--;

			if(AddTab[gObj->m_Index].OfflineTrade != true)User.OnlineTimeTick(gObj);
			Territory.Tick(gObj);
			if(AddTab[gObj->m_Index].OfflineTrade != true)AntiAFK.Tick(gObj);

			PCPoint.Tick(gObj);
			Vip.Tick(gObj);
			/*
			if (AddTab[gObj->m_Index].POST_BanTime > ct)
				AddTab[gObj->m_Index].POST_BanSignal = true;

			if (AddTab[gObj->m_Index].POST_BanSignal)
			{
				if (AddTab[gObj->m_Index].POST_BanTime < ct)
				{
					AddTab[gObj->m_Index].POST_BanSignal = false;
					Chat.MessageLog(1, c_Blue, t_BAN, gObj, "[BanPost] Your post unbaned!");
					MuOnlineQuery.ExecQuery("UPDATE Character SET BanPost = 0, BanPostTime = 0 WHERE Name = '%s'", gObj->Name);
					MuOnlineQuery.Fetch();
					MuOnlineQuery.Close();
				}
			}

			if (AddTab[gObj->m_Index].CHAT_BanTime > ct)
				AddTab[gObj->m_Index].CHAT_BanSignal = true;

			if (AddTab[gObj->m_Index].CHAT_BanSignal)
			{
				if (AddTab[gObj->m_Index].CHAT_BanTime < ct)
				{
					AddTab[gObj->m_Index].CHAT_BanSignal = false;
					Chat.MessageLog(1, c_Blue, t_BAN, gObj, "[BanChat] Your chat unbaned!");
					MuOnlineQuery.ExecQuery("UPDATE Character SET BanChat = 0, BanChatTime = 0 WHERE Name = '%s'", gObj->Name);
					MuOnlineQuery.Fetch();
					MuOnlineQuery.Close();
				}
			}
			*/
			// # -------------- # //
		}										
		/*
#ifdef _GS
		if (ct.GetSecond() == 0)
		{
			char QueryTempTime[50];
			strcpy(QueryTempTime, Utilits.SetDate(ct));
			MuOnlineQuery.ExecQuery("UPDATE Character SET BanChat = 0, BanChatTime = 0 WHERE BanChat = 1 AND BanChatTime < '%s'", QueryTempTime);
			MuOnlineQuery.Fetch();
			MuOnlineQuery.Close();
			MuOnlineQuery.ExecQuery("UPDATE Character SET BanPost = 0, BanPostTime = 0 WHERE BanPost = 1 AND BanPostTime < '%s'", QueryTempTime);
			MuOnlineQuery.Fetch();
			MuOnlineQuery.Close();
			MuOnlineQuery.ExecQuery("UPDATE Character SET CtlCode = 0, BanCharTime = 0 WHERE CtlCode = 1 AND BanCharTime < '%s'", QueryTempTime);
			MuOnlineQuery.Fetch();
			MuOnlineQuery.Close();
			Me_MuOnlineQuery.ExecQuery("UPDATE MEMB_INFO SET bloc_code = 0, BanAccTime = 0 WHERE bloc_code = 1 AND BanAccTime < '%s'", QueryTempTime);
			Me_MuOnlineQuery.Fetch();
			Me_MuOnlineQuery.Close();
		}
		
#endif
		*/
		Security.Tick();
		HappyHour.TickTimerHappyHour();
#ifdef _GS
		Moss.CheckTime();	 	
#endif	
		Sleep(1000);
		Log.Online_All = Temp_All;
		Log.Online_Gms = Temp_Gms;
	}
	return 1;	
} 
extern "C" __declspec (dllexport) void __cdecl RMST()
{
	DWORD OldProtect;
	if(VirtualProtect(LPVOID(0x401000), GSSIZE, PAGE_EXECUTE_READWRITE, &OldProtect))
	{	 
		//Protection.Load(); // Load of Protection 
		//if(!Protection.CheckFeature(Protection.Private))::ExitProcess(0); 

		//Create Log folder in GameServer
		CreateDirectory(IAJuliaConsoleLogs,NULL);	
		CreateDirectory(IAJuliaChatLogs,NULL);
		CreateDirectory(IAJuliaLog,NULL);	
		//
		srand((unsigned int)time(NULL));
		//
		Sleep(500);
		Log.LoggerInit();
		Sleep(500);
		Log.ConsoleOutPut(0, c_Green,t_NULL,"IA Julia 1.1.%d.%d Season 4.6", dBuild, dCommit);
		Log.ConsoleOutPut(0, c_Green,t_NULL,"Official Website: http://imaginationarts.net/");
		Log.ConsoleOutPut(0, c_Green,t_NULL,"Compile Date: %s %s", __DATE__, __TIME__);
		//if(Protection.CheckFeature(Protection.Private))
		Log.ConsoleOutPut(0, c_Red,t_NULL,"Registered to %s, thank you to support us.", dOwner);  
		Log.ConsoleOutPut(0, c_Green,t_NULL,"Credits: Mu Community, Imagination Arts");
		Log.ConsoleOutPut(0, c_Green,t_NULL,"Please report any bugs that you found!\n-----------------------------------------------------\n");
		//
		LoadQuery();
		Maps.MapInit();
		Fixes.ASMFixes();
		Socket.Load();
		Configs.LoadAll();
		ResetSystem.Init(); 
		#ifdef _GS
		OfflineTrade.InitOfflineTrade(); //Beta
		
			if(DuelSystem.Config.Enabled)
			{
				DuelSystem.DuelCreateThread();
				Utilits.HookThis((DWORD)&HookSetDuelOption,0x004037B5);
				Utilits.HookThis((DWORD)&HookIsDuelEnable,0x00404BCE);
				Utilits.HookThis((DWORD)&HookIsOnDuel,0x00404B56);
				Utilits.HookThis((DWORD)&HookDuelCheck1,0x00403017);
				Utilits.HookThis((DWORD)&HookDuelCheck2,0x004012DA);
				Utilits.HookThis((DWORD)&GSgObjUserDie,0x0040367A);
			}
			Utilits.HookThis((DWORD)&CheckItemType,0x00402E9B); //Socket
			Utilits.HookThis((DWORD)&ProtocolCore, 0x004038BE);
			Utilits.HookThis((DWORD)&gObjGameClose_Func, 0x004034B8);
			Utilits.HookThis((DWORD)&ProtocolCoreSend,0x004055BF);			// DataSend hook
			Utilits.HookThis((DWORD)&MyObjCalCharacter,0x004031A7);
			Utilits.HookThis((DWORD)&MonsterDie, 0x004184C4);
			Utilits.HookThis((DWORD)&GCEquipmentSendHook, 0x00407509);
			Utilits.HookThis((DWORD)&GCKillPlayerExpSendHook, 0x00406D11);
			Utilits.HookThis((DWORD)&MyItemSerialCreateSend, 0x00407004);
			Utilits.HookThis((DWORD)&MygEventMonsterItemDrop, 0x00402AD1);
			Utilits.HookThis((DWORD)&GOBJGetIndex,0x00404D18);
			Utilits.HookThis((DWORD)&gObjLevelUpPointAddEx,0x00406D7F);
			Utilits.HookThis((DWORD)&gObjPlayerKiller, 0x0040655F);
			Utilits.HookThis((DWORD)&gObjAttack, 0x00403CA6);
			Utilits.HookThis((DWORD)&gObjTradeOkButton, 0x00404A93);
			Utilits.HookThis((DWORD)&GSItemDurRepaire, 0x00405097);
			Utilits.HookThis((DWORD)&gObjInventoryMoveItemEx, 0x004021AD);
			Utilits.HookThis((DWORD)&CGItemDropRequestEx, 0x00401163);
		#endif

		#ifdef _GS_CS 
			Utilits.HookThis((DWORD)&CheckItemType,0x00402E32); //Socket
			Utilits.HookThis((DWORD)&ProtocolCore, 0x00403A17); 
			Utilits.HookThis((DWORD)&ProtocolCoreSend,0x00405AE7); 			// DataSend hook
			Utilits.HookThis((DWORD)&gObjGameClose_Func, 0x00403599);   
			Utilits.HookThis((DWORD)&MyObjCalCharacter,0x004031F7);		   
			Utilits.HookThis((DWORD)&MonsterDie, 0x0041A1AE);
			Utilits.HookThis((DWORD)&GCEquipmentSendHook, 0x00407E37);
			Utilits.HookThis((DWORD)&GCKillPlayerExpSendHook, 0x0040751D); 		
			Utilits.HookThis((DWORD)&MygEventMonsterItemDrop, 0x004029F0);
			Utilits.HookThis((DWORD)&GOBJGetIndex,0x00405114);	
			Utilits.HookThis((DWORD)&gObjLevelUpPointAddEx,0x004075B3);
			Utilits.HookThis((DWORD)&gObjPlayerKiller, 0x00406C8A);
			Utilits.HookThis((DWORD)&gObjAttack, 0x00403E72);
			Utilits.HookThis((DWORD)&gObjTradeOkButton, 0x00404E08);
			Utilits.HookThis((DWORD)&GSItemDurRepaire, 0x0040551A);
			Utilits.HookThis((DWORD)&gObjInventoryMoveItemEx, 0x00401F96);  
			Utilits.HookThis((DWORD)&CGItemDropRequestEx, 0x004082F6); 
		#endif 

		DWORD ThreadID;
		HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MainTick, NULL, 0, &ThreadID);//False	2	1173	V513	Use _beginthreadex/_endthreadex functions instead of CreateThread/ExitThread functions.	IA Julia 1.x.x	lite.cpp	148	False

		if ( hThread == 0 )
		{
			Log.ConsoleOutPut(1, c_Red, t_Error, "CreateThread() failed with error %d", GetLastError());
			return;
		}

		CloseHandle(hThread);


		hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)NewsSystem, NULL, 0, &ThreadID);//False	2	1175	V513	Use _beginthreadex/_endthreadex functions instead of CreateThread/ExitThread functions.	IA Julia 1.x.x	lite.cpp	159	False

		if ( hThread == 0 )
		{
			Log.ConsoleOutPut(1, c_Red, t_Error, "CreateThread() failed with error %d", GetLastError());
			return;
		}

		CloseHandle(hThread);

		/*if(!Protection.CheckFeature(Protection.Private))
		{
			hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)FreeVersionAdv, NULL, 0, &ThreadID);//False	2	1175	V513	Use _beginthreadex/_endthreadex functions instead of CreateThread/ExitThread functions.	IA Julia 1.x.x	lite.cpp	159	False

			if ( hThread == 0 )
			{
				Log.ConsoleOutPut(1, c_Red, t_Error, "CreateThread() failed with error %d", GetLastError());
				return;
			}

			CloseHandle(hThread);
			
		}*/
		#ifdef _GS 
			hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MonsterAddTick, NULL, 0, &ThreadID);//False	2	1177	V513	Use _beginthreadex/_endthreadex functions instead of CreateThread/ExitThread functions.	IA Julia 1.x.x	lite.cpp	170	False

			if ( hThread == 0 )
			{
				Log.ConsoleOutPut(1, c_Red, t_Error, "CreateThread() failed with error %d", GetLastError());
				return;
			}

			CloseHandle(hThread);
		#endif
	}
} 